% Tekst stworzony przez Marcina Lewandowskiego na zajęcia projektowe z~przedmiotu 'Rozproszone Systemy Operacyjne' (RSO) na wydziale Elektroniki i~Technik Informacyjnych Politechniki Warszawskiej %
\chapter{Wady i~zalety Neo4j}
%\chapterWithAuthor{Wady i~zalety Neo4j}{Marcin Lewandowski}
\label{chap:wadyizalety}

Neo4j, jako grafowa baza danych typu NoSQL, jest przeznaczona pod pewną klasę zastosowań. Implikuje to posiadanie pewnych zalet w~przypadku zastosowań zgodnych z~przeznaczeniem Neo4j oraz wad, gdy narzędzie używane jest jako konwencjonalna baza danych. Neo4j jest zaprojektowane do przechowywania i~manipulowania danych grafowych i~pół-strukturalnych (ang. semi-structured) i~sprawdza się znacznie lepiej w~takich rozwiązaniach od relacyjnych baz danych. Analogicznie, w~sytuacjach przeciwnych prym wiodą rozwiązania relacyjne.

\section{Zalety Neo4j}
\label{sec:zalety}

Do wyraźnych, charakterystycznych atutów rozwiązania Neo4j należą:

\begin{enumerate}
	\item Wydajność -- Neo4j zostało stworzone z~myślą o~wydajności. Rzeczywiście, opisywane rozwiązanie pozwala uzyskać nawet kilkudziesięciokrotny wzrost wydajności w~porównaniu z~analogicznymi problemami rozwiązywanymi za pomocą relacyjnych baz danych. Ponieważ wydajność można mierzyć na wiele sposobów, szczegółowy opis wydajności znajduje się w~podrozdziale~\ref{sec:wydajnosc}.
	\item Skalowalność -- to drugi paradygmat wykorzystany przy tworzeniu Neo4j. Rozwiązanie pozwala na przechowywanie ponad 100 milionów elementów (węzłów, atrybutów oraz związków) na jednej maszynie i~wciąż sprawne nimi zarządzanie~\cite{NeoDBTechnoIntro}.
	\item Transakcje ACID -- pełna tranzakcyjność, wspiera JTA/JTS, XA, 2PC, wykrywa zakleszczenia~\cite{NeoTransactions}.
	\item Łatwa i~wydajna reprezentacja pół-strukturalnych danych, sieci i~grafów -- Neo4j jest stworzony do przechowywania danych pół-strukturalnych (odpowiadających tabeli z~wieloma kolumnami atrybutowymi, które nie są wypełniane w~większości krotek)~\cite{NeoDBTechnoIntro}.
	\item Łatwe modyfikowanie struktury -- ponieważ Neo4j nie używa statycznych tabel z~krotkami, lecz cała struktura danych jest w~formie łatwo modyfikowalnego grafu~\cite{NeoDBTechnoIntro}.
	\item Rozwiązanie dyskowe (ang. disk-base) -- przeznaczone do przechowywania struktur na dyskach twardych. Zoptymalizowane pod względem wydajności i~skalowalności na tychże dyskach. Wsparcie SSD~\cite{NeoKicks}.
	\item Brak potrzeby obiektowo-relacyjnego mapowania (ang. Object-relational mapping) -- w~przeciwieństwie do relacyjnych baz danych, nie są konieczne odpowiednie mechanizmy do konwersji niekompatybilnych danych zawartych w~tabelach do obiektów.
	\item Lekkość (ang. light-weight) rozwiązania -- Neo4j jest rozwiązaniem małym i~lekkim. Jako komponent Java (pojedynczy plik nieprzekraczający 1MB~\cite{NeoKicks}), nie potrzebuje dodatkowych platform uruchomieniowych, a~mimo to zapewnia wydajność na skalę serwerową~\cite{ComparisonGraphAndRelational}.
	\item Solidność (ang. robust) - Neo4j jest obecnie dojrzałą technologią. Było używane przez lata w~wymagających środowiskach działających bez przerwy~\cite{NeoDBTechnoIntro}.
	\item Wolne oprogramowanie (ang. open source) -- Neo4j w~wersji 'Community' jest dostępne na licencji GPLv3, natomiast wersje 'Advanced' oraz 'Enterprise' są dostępne na licencji AGPLv3 lub komercyjnej~\cite{NeoOfficial}.
\end{enumerate}

\section{Wady Neo4j}
\label{sec:wady}

Neo4j ma również swoje wady z~których część jest związana z~przyjętymi założeniami rozwiązania:

\begin{enumerate}
	\item Bezpieczeństwo~\cite{ComparisonGraphAndRelational} -- Neo4j nie posiada wbudowanych rozwiązań zabezpieczających. Zakłada, że jest uruchomione w~zaufanym środowisku.
	\item Brak wsparcia dla wielu użytkowników~\cite{ComparisonGraphAndRelational} -- obsługa wielu użytkowników musi być realizowana na poziomie aplikacyjnym.
	\item Gorsza wydajność dla strukturalnych danych - Neo4j, jako rozwiązanie grafowe, źle się spisuje dla danych, które dobrze są opisywane w~relacyjnych bazach danych\cite{NeoDBTechnoIntro}. Szczegóły opisane są w~podrozdziale~\ref{sec:wydajnosc}.
	\item Gorsza wydajność dla danych liczbowych i~dat -- Neo4j używa Lucene, które jest zoptymalizowane do indeksowania danych tekstowych~\cite{ComparisonGraphAndRelational}.
	\item Niepopularność grafowego podejścia -- ze względu na wielką popularność relacyjnych baz danych, każde rozwiązanie grafowej bazy danych (w tym Neo4j) wymaga od użytkowników nauki nie tylko nowych narzędzi, ale i~odmiennego podejścia do przechowywania i~zarządzania danymi. Jednocześnie, w~porównaniu ze społecznością związaną z~relacyjnymi bazami danych, użytkownicy Neo4j mają mniejsze wsparcie od użytkowników tejże bazy danych~\cite{NeoDBTechnoIntro}.
	\item Brak alternatywnych implementacji~\cite{NeoDBTechnoIntro,IntroToGraphDB} -- wprawdzie to nie wada sama w~sobie, lecz brak innych implementacji wystawia Neo4j na ryzyko zastoju i~braku rozwijania.
	\item Brak wyzwalaczy (ang. trigger) -- Planowane jest ich wprowadzenie w~przyszłości~\cite{NeoKicks}.
%	\item Problematyczne użytkowanie -- wprawdzie łatwość zapytań w~bazie danych zależy w~znacznym stopniu od rodzaju danych, które należy pozyskać, jednak, generalnie, można powiedzieć, że przechodzenie po bazie danych grafowej za pomocą bytu 'Traversal' (brak dobrego polskiego odpowiednika - wędrowiec?) jest bardziej skomplikowane oraz istnieje ryzyko zbytecznych pętli lub rekursywnego i~kosztownego przechodzenia po węzłach\cite{ComparisonGraphAndRelational}. Relacyjne bazy danych korzystają po prostu z~SQL. Do wersji 1.4 Neo4j dołączono Cypher - język zapytań, więc problem stracił na znaczeniu. W~Neo4j brak jest zapytań typu ad-hoc~\cite{IntroToGraphDB}.
	\item Niedoskonałe narzędzia do zarządzania danymi -- zwłaszcza w~porównaniu z~relacyjnymi bazami danych, narzędzia do zarządzania Neo4j mają mniejsze możliwości~\cite{NeoDBTechnoIntro,IntroToGraphDB}.
\end{enumerate}

\section{Aspekt wydajności Neo4j}

\label{sec:wydajnosc}

Nie powinno być zaskoczeniem, iż każde dedykowane rozwiązanie jest dobre w~tym, do czego zostało przewidziane. Nie inaczej jest i~w~tym przypadku. Zarówno relacyjne jak i~graficzne bazy danych spełniają dobrze swoją funkcję.

W szczególności Neo4j, jako dedykowane narzędzie do tworzenia i~zarządzania grafowymi bazami danych, pozwala uzyskać wydajność większą o rzędy wielkości w~porównaniu do relacyjnych baz danych. Materiały wprowadzające do Neo4j~\cite{IntroToGraphDB} zachwalają to rozwiązanie pokazując niezwykle optymistyczne wybrane wyniki ukazane w~tablicy~\ref{table:relvsneo}.

\begin{table}

  \begin{tabular}{ l | r | r }
    Baza danych & Liczba węzłów & Czas zapytania \\ \hline
    Relacyjna & 1 000 & 2 000 ms \\
    Neo4j & 1 000 & 2 ms \\
    Neo4j & 1 000 000 & 2 ms \\
  \end{tabular}

  \label{table:relvsneo}
  \caption{Porównanie czasów zapytań w~bazach danych.}
  
\end{table}

Testy na danych grafowych~\cite{MySQLvsNeo} pokazują wyższą wydajność rozwiązania Neo4j. Podsumowując zawartość opisywanych testów, przejrzenie struktury grafu oraz zwrócenie około 350 milionów wierzchołków zajęło rozwiązaniu Neo4j niecałe 15 minut. Baza danych MySQL nie ukończyła analogicznego zadania nawet po upływie dwóch godzin.

W innym teście~\cite{NeoDBTechnoIntro} na komputerze z~procesorem Core 2 Duo 2.4GHz oraz 8GB pamięci RAM (z czego 2GB przypisane maszynie JVM dla Neo4j) przejście po ponad 100 000 relacjach zajmuje mniej niż 10 sekund.

Trzeba jednak mieć na uwadze, że powyższe testy były wykonywane na danych trzymanych w~postaci grafów. Można podejrzewać, że same wyniki były dobrane tak, aby pokazywać zalety Neo4j, ale nie ujawniać wad. Bazy relacyjne nie są przystosowane do tego typu reprezentacji, gdyż wymagają kosztownych złączeń swoich tabel.

Nieco bardziej ogólne testy (jednak również na danych w~postaci grafu) są ukazane w~innym dokumencie~\cite{ComparisonGraphAndRelational} porównującym rozwiązanie MySQL z~Neo4j. Po pierwsze, w~przypadku przechowywania w~bazie danych elementów o typach liczbowych (integer) oraz ciągów znaków o długości 4kb, baza Neo4j zajmowała o 80-100\% więcej przestrzeni dyskowej. W~przypadku ciągów znaków o długości 32kb wielkość bazy grafowej była średnio 20\% większa. Stosunki te były mniej więcej stałe w~przypadku różnych ilości elementów w~bazach. Natomiast w~kwestii wydajności wykonano szereg różnych testów. Testy wykonano na drzewach o różnej liczbie węzłów i~trzech wspomnianych wyżej typach. Część wniosków:

\begin{enumerate}
	\item Gdy wyszukiwano w~bazie węzłów niepołączonych z~innymi, dla liczby węzłów wynoszącej 100 000 (największe drzewa) zyskiwało rozwiązanie Neo4j. Jednak gdy drzewa były mniejsze, obie bazy danych miały nieznacznie różniące się wyniki (dane znakowe) lub MySQL było szybsze nawet około siedmiokrotnie (dane liczbowe), baza MySQL nie potrzebowała wykonywać żadnych połączeń tabel.
	\item Przeszukiwanie grafu do różnych głębokości pokazało przewagę Neo4j (od około \mbox{3-krotną} do \mbox{20-krotną}) na bazie Neo4j dla wszystkich typów danych.
	\item Policzenie ilości węzłów, gdzie wartość liczbowa była równa zadanej zajęło Neo4j od około 8 razy więcej czasu (największe drzewa) do około 100 razy (najmniejsze drzewa), różnica polega głównie na różnym sposobie dostępu do danych.
	\item W~przypadku przeszukiwania danych znakowych rozwiązanie MySQL było wyraźnie lepsze dla małych grafów (1000 węzłów), ale dla wszystkich większych Neo4j pokazywało znaczną (nawet ponad 100-krotną) przewagę.
\end{enumerate}

Dostępne wyniki testów pokazały znaczne różnice w~wydajności. Praktycznie wszystkie zgadzają się z~teoretycznymi oczekiwaniami, na podstawie wewnętrznej budowy baz danych.
